// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
"use strict";

((window) => {
  const { ObjectAssign } = window.__bootstrap.primordials;

  class Vector3 {
    constructor(x, y, z) {
      this.x = x;
      this.y = y;
      this.z = z;
    }
  }

  class Vector2 {
    constructor(x, y) {
      this.x = x;
      this.y = y;
    }
  }

  class Vector4 {
    constructor(x, y, z, w) {
      this.x = x;
      this.y = y;
      this.z = z;
      this.w = w;
    }
  }

  let KeyCode = {
    Space:0,
    Apostrophe:1,
    Comma:2,
    Minus:3,
    Period:4,
    Slash:5,
    Key1:6,
    Key2:7,
    Key3:8,
    Key4:9,
    Key5:10,
    Key6:11,
    Key7:12,
    Key8:13,
    Key9:14,
    Key0:15,
    Numlock:16,
    Numpad0:17,
    Numpad1:18,
    Numpad2:19,
    Numpad3:20,
    Numpad4:21,
    Numpad5:22,
    Numpad6:23,
    Numpad7:24,
    Numpad8:25,
    Numpad9:26,
    Semicolon:27,
    Equal:28,
    A:29,
    B:30,
    C:31,
    D:32,
    E:33,
    F:34,
    G:35,
    H:36,
    I:37,
    J:38,
    K:39,
    L:40,
    M:41,
    N:42,
    O:43,
    P:44,
    Q:45,
    R:46,
    S:47,
    T:48,
    U:49,
    V:50,
    W:51,
    X:52,
    Y:53,
    Z:54,
    LeftBracket:55,
    Backslash:56,
    RightBracket:57,
    GraveAccent:58,
    World1:59,
    World2:60,
    Escape:61,
    Enter:62,
    Tab:63,
    Backspace:64,
    Insert:65,
    Delete:66,
    Right:67,
    Left:68,
    Down:69,
    Up:70,
    PageUp:71,
    PageDown:72,
    Home:73,
    End:74,
    CapsLock:75,
    ScrollLock:76,
    NumLock:77,
    PrintScreen:78,
    Pause:79,
    F1:80,
    F2:81,
    F3:82,
    F4:83,
    F5:84,
    F6:85,
    F7:86,
    F8:87,
    F9:88,
    F10:89,
    F11:90,
    F12:91,
    F13:92,
    F14:93,
    F15:94,
    F16:95,
    F17:96,
    F18:97,
    F19:98,
    F20:99,
    F21:100,
    F22:101,
    F23:102,
    F24:103,
    Snapshot:104,
    Scroll:105,
    Back:106,
    Return:107,
    Compose:108,
    Caret:109,
    F25:110,
    Kp0:111,
    Kp1:112,
    Kp2:113,
    Kp3:114,
    Kp4:115,
    Kp5:116,
    Kp6:117,
    Kp7:118,
    Kp8:119,
    Kp9:120,
    KpDecimal:121,
    KpDivide:122,
    KpMultiply:123,
    KpSubtract:124,
    KpAdd:125,
    KpEnter:126,
    KpEqual:127,
    LeftShift:128,
    LeftControl:129,
    LeftAlt:130,
    LeftSuper:131,
    RightShift:132,
    RightControl:133,
    RightAlt:134,
    RightSuper:135,
    Menu:136,
    Unknown:137,
  }

  class Input {
    static isKeyPress(code){
        return Deno.core.ops.op_is_key_pressed(code)
    }
  }

  let ComponentType = {
    Transform: 0,
    Rigidbody2d: 1,
    Collider2d: 2,
  };

  class Component {}

  class Transform extends Component {
    constructor() {
      this.position = new Vector3(0, 0, 0);
      this.rotation = new Vector3(0, 0, 0);
      this.scale = new Vector3(1, 1, 1);
    }
  }

  class Rigidbody2d {
    constructor() {
      this.mass = 1.0;
    }
  }

  class Collider2d {
    constructor() {
      this.restitution = 1.0;
      this.friction = 1.0;
    }
  }

  class Entity {
    constructor() {
      this.id = "";
      this.position = new Proxy(new Vector3(0, 0, 0), {
        get: (target, key, receiver) => {
          let vec3 = Deno.core.ops.op_get_position(this.id);
          return vec3[key];
        },
        set: (target, key, value, receiver) => {
          Reflect.set(target, key, value, receiver);
          Deno.core.ops.op_set_position(this.id, target);
          return true;
        },
      });
    }
    // position:Vector3;
    // rotation:Vector3;
    // scale:Vector3;
    // getcomponent<T extends Component>(type:Component): T | null;
    // addcomponent(type:Component);
    // removecomponent(type:Component);
    // onCreate();
    // onUpdate();
    // onDestroy();

    onCreate(id) {
      this.id = id;
      Deno.core.print("Entity Create Run!\n");
      Deno.core.print("Entity Id!");
      Deno.core.print(this.id);

      Deno.core.print(`position=${JSON.stringify(this.position)}\n`);
    }

    onUpdate(dt) {}

    getComponent(type) {}
  }
  // Extra Deno.core.*

  ObjectAssign(globalThis, {
    Alice: {
      Vector3,
      Vector2,
      Vector4,
      ComponentType,
      Component,
      Transform,
      Rigidbody2d,
      Collider2d,
      Entity,
      Input,
      KeyCode
    },
  });
})(globalThis);
